<template>
  <el-card class="title">
    <el-button icon="i-ep-Promotion" type="warning" @click="fresh">重新加载</el-button>
    <code-editor-button v-model="m2" type="primary" label="查看源码" icon="i-ep-search" />
    <el-button icon="i-ep-Promotion" type="success" @click="save">提交源码</el-button>
    <el-divider direction="vertical" />
    <el-button icon="i-ep-Plus" type="primary" @click="addModel">新建模型</el-button>
  </el-card>

  <el-card>
    <el-row class="title">
      <el-col :span="3"><span>模型名称</span></el-col>
      <el-col :span="6"><span>附加表</span></el-col>
      <el-col :span="12"><span>模型操作</span></el-col>
    </el-row>
    <template v-for="(model, key) in m2.models || {}" :key="key">
      <el-row class="model-row" align="middle">
        <el-col :span="3">
          <el-tag
            closable
            :type="model.inner ? 'info' : ''"
            @close="removeModel(key)"
            @click="editModel(key)"
          >
            {{ model.label }}
          </el-tag>
        </el-col>
        <el-col :span="6">
          <el-select
            v-if="!model.inner"
            v-model="m2.models[key].inners"
            multiple
            style="width: 240px"
          >
            <el-option
              v-for="item in inners"
              :key="item.name"
              :label="item.label"
              :value="item.name"
            />
          </el-select>
        </el-col>
        <el-col :span="12" class="model-actions">
          <el-tag
            v-for="view in m2.controllers[key].views"
            :key="view.name"
            class="view-tag"
            closable
            :type="getModelColor(view)"
            @close="removeView(key, view.name)"
            @click="editView(key, view.name)"
          >
            <el-icon><i-ep-aim /></el-icon>{{ view.title || view.name }}
          </el-tag>
          <el-tag type="warning" @click.stop="addView(key, 'Form')">
            <el-icon><i-ep-tickets /></el-icon>新表单
          </el-tag>
          <el-tag type="success" @click.stop="addView(key, 'Curd')">
            <el-icon><i-ep-credit-card /></el-icon>新表格
          </el-tag>
        </el-col>
        <!--        <el-col :span="4">-->
        <!--          <el-icon class="op-button" @click.stop="editModel(key)">-->
        <!--            <i-ep-setting class="op-edit" />-->
        <!--          </el-icon>-->
        <!--          <el-icon class="op-button" @click.stop="removeModel(key)">-->
        <!--            <i-ep-delete class="op-remove" />-->
        <!--          </el-icon>-->
        <!--        </el-col>-->
      </el-row>
    </template>
  </el-card>

  <el-dialog v-model="dialog" fullscreen destroy-on-close>
    <el-card>
      <maker-main
        :model-value="target"
        :series="maker.series"
        :model="maker.model"
        @update:model-value="onClose"
      />
    </el-card>
  </el-dialog>
</template>

<script lang="ts" setup>
  import {
    M2,
    m2InjectionKey,
    NamedModel,
    NamedView,
    SeriesName,
    Page2Series,
    getCurdController
  } from '../components/maker/structure';
  import { computed, markRaw, provide, Ref, ref } from 'vue';
  import { Command, View } from '../components/core';
  import CodeEditorButton from '../components/editor/CodeEditorButton.vue';
  import { ElLoading } from 'element-plus';
  import { PageName } from './pages';
  import MakerMain from '../components/maker/MakerMain.vue';

  /**
   * Maker 配置参数
   */
  interface Maker {
    series?: SeriesName;
    close?: (v: NamedModel | NamedView) => void;
    model?: NamedModel;
  }

  /**
   * TODO Inner 改为 checkbox 列表
   */

  const props = defineProps<{
    modelValue?: M2;
    url: string;
    submit: string;
  }>();

  const m2 = ref<M2>(props.modelValue || { models: {}, controllers: {}, name: '' });

  const save = () => Command.Post(props.submit, m2.value);

  provide(m2InjectionKey, () => m2.value);

  const getModelColor = (m: View) => {
    if (m.view === 'Form') return 'warning';
    if (m.view === 'Curd') return 'success';
    if (m.view === 'Chart') return 'danger';
    return '';
  };

  const inners = computed<NamedModel[]>(() =>
    Object.values(m2.value.models).filter((m) => m.inner)
  );

  function removeModel(name: string) {
    if (m2.value.models[name]) delete m2.value.models[name];
  }
  // function removeController(name: string) {
  //   if (m2.value.controllers[name]) delete m2.value.controllers[name];
  // }
  function removeView(controller: string, name: string) {
    if (m2.value.controllers[controller]?.views?.[name]) {
      delete m2.value.controllers[controller].views[name];
    }
  }

  const dialog = ref(false);

  const emptyView = markRaw<NamedView>({ view: '', name: '' });

  /**
   * 面板参数
   */
  const maker = ref<Maker>({});

  /**
   * 面板的结果
   */
  const target = ref<NamedView | NamedModel>(emptyView);

  const openMaker = (
    close: (v: NamedModel | NamedView) => void,
    series?: SeriesName,
    model?: NamedModel
  ) => {
    maker.value = {
      series,
      close,
      model
    };

    dialog.value = true;
  };
  const onClose = (v: Ref<NamedModel | NamedView>) => {
    maker.value.close?.(v.value);
    maker.value = {};
    dialog.value = false;
  };

  const modelHandle = () => {
    openMaker((v: NamedModel) => {
      if (v.name) {
        m2.value.models[v.name] = v;
        addController(v.name);
      }
    }, 'model');
  };
  const addModel = () => {
    target.value = { name: '' };
    modelHandle();
  };
  const editModel = (name: string) => {
    if (m2.value.models[name]) target.value = m2.value.models[name];
    modelHandle();
  };

  const addController = (name: string) => {
    if (!m2.value.models[name]) return;
    m2.value.controllers[name] = getCurdController(name);
  };

  const toController = (controller: string, view: PageName) => {
    if (!m2.value.controllers[controller].views) m2.value.controllers[controller].views = {};

    const model = m2.value.controllers[controller].model;
    if (!model) return;

    const series = Page2Series(view);

    openMaker(
      (v) => {
        if (v.name)
          m2.value.controllers[controller].views[v.name] = {
            ...v,
            view
          };
      },
      series,
      m2.value.models[model]
    );
  };
  function addView(controller: string, view: PageName = 'Form') {
    target.value = emptyView;
    toController(controller, view);
  }
  function editView(controller: string, name: string, page?: PageName) {
    if (!m2.value.controllers[controller]?.views?.[name]) {
      addView(controller, page);
      return;
    }
    const view = m2.value.controllers[controller]?.views?.[name];
    target.value = view;

    if (typeof view.view !== 'string') return;

    toController(controller, view?.view as PageName);
  }

  const fresh = async () => {
    const loading = ElLoading.service({
      lock: true,
      text: 'Loading',
      background: 'rgba(0, 0, 0, 0.7)'
    });
    const module = m2.value.name;
    m2.value = (await Command.Post(props.url, {
      module,
      value: JSON.stringify(m2)
    })) as M2;
    loading.close();
  };
</script>
<script lang="ts">
  // 声明额外的选项
  // noinspection JSUnusedGlobalSymbols
  export default {
    inheritAttrs: false
  };
</script>
<style scoped>
  .title {
    margin-bottom: 15px;
  }

  .model-row {
    margin-bottom: 10px;
    background-color: #e0e0e0;
    padding: 10px;
    border-radius: 9px;
    height: 52px;
  }

  /*noinspection CssUnusedSymbol*/
  .model-actions .el-tag {
    margin-right: 10px;
  }
</style>
